using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Rapier.Kodachi.Engine;
using Rapier.Kodachi.Shared;
using SharpBits.Base;
using Rapier.Kodachi.Actions;
using System.Diagnostics;

namespace Rapier.Kodachi.WinForm
{
   public partial class WindowMain : Form,IView
   {
        #region Data Members
        internal static Controller controller;
        private NotifyIcon notifyIcon = new NotifyIcon();
        private IDisplay display;
        private HotKey hotKey;
        private DateTime lastActivatedDateTime;
        private System.Windows.Forms.MenuItem rescanItem;

        //Clean this up later...Jay
        private BitsJob checkVersionJob;
        private string downloadFile = System.Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + @"\Rapier Software\Kodachi\webVersion.xml";
        #endregion

        #region Properties
        private Host _Host;
        public Host Host
        {
            get { return _Host; }
            set { _Host = value; }
        }
        #endregion

        #region Constructor
        public WindowMain()
        {
            controller = new Controller(this);
            Host = new Host(controller);
            Host.Context = System.Threading.SynchronizationContext.Current;

            InitializeComponent();

            notifyIcon.Text = "Kodachi";
            notifyIcon.Visible = true;
            notifyIcon.Icon = Rapier.Kodachi.WinForm.Properties.Resources.Kodachi;
            BuildContextMenu();
            notifyIcon.DoubleClick += new EventHandler(notifyIcon_DoubleClick);

            //display = new DisplayWPF(controller);
            display = new Display(controller);
            RegisterHotKey();
            System.Windows.Forms.Application.EnableVisualStyles();
            System.Windows.Forms.Application.ApplicationExit += new EventHandler(Application_ApplicationExit);

            //PerformUpdateCheck();
            
            this.Opacity = 0;
            this.Visible = false;
            this.Hide();
        }

      void Application_ApplicationExit(object sender, EventArgs e)
      {
         controller.Shutdown();
      }

        public void AddInternalActions()
        {
            // Add internal actions
            Host.AddAction(new SubmitFeedback());
            Host.AddAction(new ShowOptions());
            Host.AddAction(new About());
            Host.AddAction(new ShowHelp());
            Host.AddAction(new Quit());
            Host.AddAction(new Rescan());
         }

        #region Event Handlers
        private void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            OpenOptionsDialog();
        }


        private void hotKey_HotKeyPressed(object sender, EventArgs e)
        {
            TimeSpan timeSpan = DateTime.Now - lastActivatedDateTime;
            if (timeSpan.TotalSeconds < .25)
                return;

            hotKey.Enable = false;
            if (display.IsVisible)
            {
                if (controller.Settings.HotKeyHides)
                {
                    controller.Hide();
                }
            }
            else
            {
                controller.Activate();
            }
            RegisterHotKey();
            lastActivatedDateTime = DateTime.Now;
        }

        private void quitItem_Click(object sender, EventArgs e)
        {
           System.Windows.Forms.Application.Exit();
        }

        private void helpItem_Click(object sender, EventArgs e)
        {
            controller.ShowHelp();
        }

        private void aboutItem_Click(object sender, EventArgs e)
        {
            controller.ShowAbout();
        }

        private void optionsItem_Click(object sender, EventArgs e)
        {
            OpenOptionsDialog();
        }

        private void rescanItem_Click(object sender, EventArgs e)
        {
            controller.UpdateCatalog();
        }

        private void feedbackItem_Click(object sender, EventArgs e)
        {
            FeedbackWindow fw = new FeedbackWindow();
            fw.Show();
        }

        private void OpenOptionsDialog()
        {
            controller.ShowOptions();
            RegisterHotKey();
        }

        private void registerHotKeyTimer_Tick(object sender, EventArgs e)
        {
            (sender as Timer).Enabled = false;
            RegisterHotKey();
            (sender as Timer).Enabled = true;
        }
        #endregion
        #endregion

        #region Overrides
        //protected override void OnInitialized(EventArgs e)
        //{
        //    base.OnInitialized(e);
        //    controller.Startup();
        //}
      protected override void OnLoad(EventArgs e)
      {
         base.OnLoad(e);
         controller.Startup();
      }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            notifyIcon.Visible = false;
        }
        #endregion

        #region IView Members
        public bool ShowWaiting
        {
            get { return display.ShowWaiting; }
            set { display.ShowWaiting = value; }
        }

       public bool RescanAvailable
       {
          get
          {
             return rescanItem.Enabled;
          }
          set
          {
             rescanItem.Enabled = value;
          }
       }

        public string TextEntryString
        {
            get { return display.TextEntryString; }
            set { display.TextEntryString = value; }
        }

        public bool ShowOptions()
        {
            Sheath();
            
           //OptionsWPF o = new OptionsWPF(controller);
            Options o = new Options(controller);
           
           o.ShowDialog();
           if (o.RestartNeeded)
           {
              return true;
           }

            return false;

        }

        public void Expose()
        {
            display.Expose();
        }

        public void Sheath()
        {
            display.Sheath();
            //display = new DisplayWPF(controller);
            display = new Display(controller);
        }

       public void RefreshActions()
       {
           AddInternalActions();
       }

      private delegate void DisplayUpdateEvent();
        public void Update()
        {
           if (InvokeRequired)
           {
              BeginInvoke(new DisplayUpdateEvent(Update), null);
              return;
           }

           display.UpdateDisplay();
        }
        #endregion

        #region Private Methods
        private void BuildContextMenu()
        {
            System.Windows.Forms.ContextMenu menu = new System.Windows.Forms.ContextMenu();

            System.Windows.Forms.MenuItem feedbackItem = new System.Windows.Forms.MenuItem("Submit feedback...");
            feedbackItem.Click += new EventHandler(feedbackItem_Click);
            menu.MenuItems.Add(feedbackItem);

            // private member so we can access it in RescanAvailable property
            rescanItem = new System.Windows.Forms.MenuItem("Rescan");
            rescanItem.Enabled = false;
            rescanItem.Click += new EventHandler(rescanItem_Click);
            menu.MenuItems.Add(rescanItem);

            System.Windows.Forms.MenuItem optionsItem = new System.Windows.Forms.MenuItem("Options...");
            optionsItem.Click += new EventHandler(optionsItem_Click);
            menu.MenuItems.Add(optionsItem);

            System.Windows.Forms.MenuItem aboutItem = new System.Windows.Forms.MenuItem("About...");
            aboutItem.Click += new EventHandler(aboutItem_Click);
            menu.MenuItems.Add(aboutItem);

            System.Windows.Forms.MenuItem helpItem = new System.Windows.Forms.MenuItem("Help...");
            helpItem.Click += new EventHandler(helpItem_Click);
            menu.MenuItems.Add(helpItem);

            System.Windows.Forms.MenuItem quitItem = new System.Windows.Forms.MenuItem("Quit");
            quitItem.Click += new EventHandler(quitItem_Click);
            menu.MenuItems.Add(quitItem);

            notifyIcon.ContextMenu = menu;
        }

        private void RegisterHotKey()
        {
            if (hotKey != null)
                hotKey.Enable = false;

            hotKey = new HotKey(controller.Settings.HotKey, (HotKey.HotKeyModifiers)controller.Settings.HotKeyModifiers);
            hotKey.HotKeyPressed += new EventHandler(hotKey_HotKeyPressed);
            hotKey.Enable = true;
        }

        private void PerformUpdateCheck()
        {
            try
            {
                BitsManager manager = new BitsManager();
                manager.EnumJobs(JobOwner.CurrentUser);
                checkVersionJob = manager.CreateJob("Kodachi Update", JobType.Download);
                checkVersionJob.AddFile("http://www.rapiersoftware.com/bits/CurrentVersion.Xml", downloadFile);

                checkVersionJob.OnJobTransferred += new EventHandler<JobNotificationEventArgs>(newJob_OnJobTransferred);
                checkVersionJob.OnJobError += new EventHandler<JobErrorNotificationEventArgs>(newJob_OnJobError);
                checkVersionJob.Resume();
            }
            catch
            {
            }
        }

        void newJob_OnJobError(object sender, JobErrorNotificationEventArgs e)
        {
            System.Windows.Forms.MessageBox.Show("Error...");
            System.Windows.Forms.Application.Exit();
        }

        void newJob_OnJobTransferred(object sender, JobNotificationEventArgs e)
        {
            try
            {
                checkVersionJob.Complete();
                DataSet versionInfo = new DataSet();
                versionInfo.ReadXml(downloadFile);


                Version webVersion = new Version(versionInfo.Tables["KodachiVersion"].Rows[0]["NewestVersion"].ToString());
                Version myVersion = new Version(System.Windows.Forms.Application.ProductVersion);

                if (webVersion > myVersion)
                {
                    //Start the actual new version download based on settings etc...
                    //Then when that file completes, make them run the install?
                    //For now, I pop a message as a placeholder...
                    //System.Windows.Forms.MessageBox.Show("There is a more recent version of Kodachi available...please download it now.");
                    DownloadLatest dl = new DownloadLatest();
                    dl.ShowDialog();
                    Environment.Exit(1);
                }
            }
            catch
            {
            }
        }
        #endregion
    }
   
}